package prefix.util;

import java.math.BigDecimal;
import java.math.RoundingMode;

import play.db.jpa.JPA;

public class OverallUtil {
    private static final double SCALE = 100.0;

    public static BigDecimal round2Decimal(double amt, RoundingMode rmode) {

        BigDecimal val = new BigDecimal(amt);

        // does it require rounding?
        BigDecimal Bamt = round2Decimal(amt);
        BigDecimal Bdiff = Bamt.subtract(val);
        Bdiff = Bdiff.abs();

        if (Bdiff.doubleValue() <= 0.000001) {
            return Bamt;
        }

        // Rounding required
        val = val.setScale(2, rmode);
        return val;

    }

    public static BigDecimal round2Decimal(BigDecimal amt, RoundingMode rmode) {

        // does it require rounding?
        BigDecimal Bamt = round2Decimal(amt.doubleValue());
        BigDecimal Bdiff = Bamt.subtract(amt);
        Bdiff = Bdiff.abs();

        if (Bdiff.doubleValue() <= 0.000001) {
            return Bamt;
        }

        // Rounding required
        amt = amt.setScale(2, rmode);
        return amt;

    }

    public static BigDecimal round2Decimal(BigDecimal amt) {

        long lamt = Math.round(amt.doubleValue() * SCALE);

        BigDecimal big_amt = new BigDecimal(lamt);
        big_amt = big_amt.divide(new BigDecimal(SCALE));

        return big_amt;
    }

    // This has to be review, TODO soul
    public static BigDecimal round2Decimal(double amt) {

        long lamt = Math.round(amt * SCALE);

        BigDecimal big_amt = new BigDecimal(lamt);
        big_amt = big_amt.divide(new BigDecimal(SCALE));

        return big_amt;
    }

    public static <T extends Enum<T>> boolean isIn(T t, T... values) {

        if (t == null || values == null || values.length <= 0)
            return false;
        for (int i = 0; i < values.length; i++) {
            if (values[i].equals(t))
                return true;
        }
        return false;
    }

    public static double validate(double val, double sensitivity, String debugString) throws CalculationException {
        if (val < -sensitivity)
            throw new CalculationException(CalculationException.CODE.INVALID_VALUE);

        if (Math.abs(val) <= sensitivity)
            return 0.0;
        return val;
    }

    //----------------------------------------------------------------------------------------------------------------------
    public static void validateSensitivity(double val, double sensitivity) throws CalculationException {
        if (Math.abs(val) > sensitivity)
            throw new CalculationException(CalculationException.CODE.INVALID_VALUE, " Diff=" + val
                    + " Sensistivity-limit = " + sensitivity);
    }

    public static <T extends Enum<T>> String INSQL(T... types) {
        String str = "" + types[0].ordinal();

        int len = types.length;
        for (int i = 1; i < len; i++) {
            str += "," + types[i].ordinal();
        }
        return str;
    }

    public static String getCallStackAsString(String newLine, int depth) {
        StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        StringBuilder sb = new StringBuilder();

        int i = 3;
        sb.append(ste[i++].toString());

        for (; i < ste.length && i < depth + 3; i++)
            sb.append(newLine).append(ste[i].toString());

        return sb.toString();
    }
}
